from tkinter import *
from tkinter import messagebox
import cv2
from ttkbootstrap import Style
from ttkbootstrap.toast import ToastNotification
import pandas as pd
from PIL import Image, ImageTk

# 读取 Excel 文件
df = pd.read_excel('data.xlsx')
# 序号
number_excel = df.iloc[:, 0]
# text文本问题
problem_excel = df.iloc[:, 1]
# 答案A
A_excel = df.iloc[:, 2]
# 答案B
B_excel = df.iloc[:, 3]
# 答案C
C_excel = df.iloc[:, 4]
# 答案D
D_excel = df.iloc[:, 5]
# text文本答案
daan_excel = df.iloc[:, 6]

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')


class Root:
    W = 1620
    H = 900
    question = 0
    chengji = 0
    id = None
    allSecond = 3600  # 秒数，1小时
    allSecond_x = 0
    min_x = 0
    minn = 0
    h = 0
    time = True
    label01 = None
    image = None
    image2 = None
    I_jpg = None
    star = False

    def __init__(self):
        Root.question = 0
        Root.chengji = 0
        Root.id = None
        Root.allSecond = 3600  # 秒数，1小时
        Root.allSecond_x = 0
        Root.min_x = 0
        Root.minn = 0
        Root.h = 0
        Root.time = True

        cap = cv2.VideoCapture(0)
        camera_width = 200
        camera_height = 600
        # cap.set(3, camera_width)  # 宽度设置为1920
        # cap.set(4, 50)  # 高度设置为1080
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height)

        # 下一道题
        def next_question():
            Root.question += 1
            if Root.question >= 100:
                Root.question = 100
            A_button.config(text=f"  A.{A_excel[Root.question]}")
            B_button.config(text=f"  B.{B_excel[Root.question]}")
            C_button.config(text=f"  C.{C_excel[Root.question]}")
            D_button.config(text=f"  D.{D_excel[Root.question]}")
            label100_label.config(text=f"总数\n{number_excel[Root.question]}/100")
            problem_text.config(state="normal")
            problem_text.delete(0.0, END)
            problem_text.insert(INSERT, f" {Root.question}.{problem_excel[Root.question]}")
            problem_text.config(state="disabled")
            for x in range(100):
                if buttons[x]["bg"] == "blue":
                    h = next_question_button.cget("bg")
                    buttons[x]["bg"] = f"{h}"
            if buttons[Root.question - 1]["bg"] == "green":
                buttons[Root.question - 1].config(bg="green")
            else:
                buttons[Root.question - 1].config(bg="blue")

            try:
                Root.image = Image.open(f'images/{Root.question}.jpg')
            except FileNotFoundError:
                Root.image = Image.open('images/1.png')
            Root.image2 = Root.image.resize((260, 200))
            Root.I_jpg = ImageTk.PhotoImage(Root.image2)
            Root.label01 = Label(root, image=Root.I_jpg)
            Root.label01.place(x=730, y=120)

        # 上一道题
        def previous_question():

            Root.question -= 1
            if Root.question <= 1:
                Root.question = 1
            A_button.config(text=f"  A.{A_excel[Root.question]}")
            B_button.config(text=f"  B.{B_excel[Root.question]}")
            C_button.config(text=f"  C.{C_excel[Root.question]}")
            D_button.config(text=f"  D.{D_excel[Root.question]}")
            label100_label.config(text=f"总数\n{number_excel[Root.question]}/100")
            problem_text.config(state="normal")
            problem_text.delete(0.0, END)
            problem_text.insert(INSERT, f" {Root.question}.{problem_excel[Root.question]}")
            problem_text.config(state="disabled")

            for x in range(100):
                if buttons[x]["bg"] == "blue":
                    h = next_question_button.cget("bg")
                    buttons[x]["bg"] = f"{h}"
            if buttons[Root.question - 1]["bg"] == "green":
                buttons[Root.question - 1].config(bg="green")
            else:
                buttons[Root.question - 1].config(bg="blue")

            try:
                Root.image = Image.open(f'images/{Root.question}.jpg')
            except FileNotFoundError:
                Root.image = Image.open('images/1.png')
            Root.image2 = Root.image.resize((260, 200))
            Root.I_jpg = ImageTk.PhotoImage(Root.image2)
            Root.label01 = Label(root, image=Root.I_jpg)
            Root.label01.place(x=730, y=120)

        # 100个按钮
        def button_100(anniu):
            Root.question = anniu + 1
            A_button.config(text=f"  A.{A_excel[Root.question]}")
            B_button.config(text=f"  B.{B_excel[Root.question]}")
            C_button.config(text=f"  C.{C_excel[Root.question]}")
            D_button.config(text=f"  D.{D_excel[Root.question]}")
            label100_label.config(text=f"总数\n{number_excel[Root.question]}/100")
            problem_text.config(state="normal")
            problem_text.delete(0.0, END)
            problem_text.insert(INSERT, f" {Root.question}.{problem_excel[Root.question]}")
            problem_text.config(state="disabled")

            for x in range(100):
                if buttons[x]["bg"] == "blue":
                    h = next_question_button.cget("bg")
                    buttons[x]["bg"] = f"{h}"
            if buttons[Root.question - 1]["bg"] == "green":
                buttons[Root.question - 1].config(bg="green")
            else:
                buttons[Root.question - 1].config(bg="blue")
            try:
                Root.image = Image.open(f'images/{Root.question}.jpg')
            except FileNotFoundError:
                Root.image = Image.open('images/1.png')
            Root.image2 = Root.image.resize((260, 200))
            Root.I_jpg = ImageTk.PhotoImage(Root.image2)
            Root.label01 = Label(root, image=Root.I_jpg)
            Root.label01.place(x=730, y=120)

        # 提交
        def submit():
            Root.chengji = 0
            for x in range(1, 101):
                if buttons[x - 1]["text"] == f"{daan_excel[x].upper()}":
                    Root.chengji += 1
                print(buttons[x - 1]["text"], daan_excel[x].upper())
            messagebox.showinfo("成绩单", f"成绩:{Root.chengji},利用时间:{Root.min_x}:{Root.allSecond_x}分/秒")

        # 答案A
        def a():
            buttons[Root.question - 1]["text"] = "A"
            buttons[Root.question - 1]["bg"] = "green"
            next_question()

        # 答案B
        def b():
            buttons[Root.question - 1]["text"] = "B"
            buttons[Root.question - 1]["bg"] = "green"
            next_question()

        # 答案C
        def c():
            buttons[Root.question - 1]["text"] = "C"
            buttons[Root.question - 1]["bg"] = "green"
            next_question()

        # 答案D
        def d():
            buttons[Root.question - 1]["text"] = "D"
            buttons[Root.question - 1]["bg"] = "green"
            next_question()

        def star_exam():
            if Root.time:
                Root.box = messagebox.askokcancel("考试提示", "确定开始考试")
                if Root.box:
                    video_label.place(x=Root.W - camera_width - 170, y=10)
                    for x in range(100):
                        buttons[x].config(state="normal")
                    next_question_button.config(state="normal")
                    previous_question_button.config(state="normal")
                    back_button.config(state="disabled")
                    A_button.config(state="normal")
                    B_button.config(state="normal")
                    C_button.config(state="normal")
                    D_button.config(state="normal")
                    submit_button.config(state="normal")
                    next_question()
                    Root.time = False
            if Root.box:
                Root.allSecond -= 1
                Root.allSecond_x += 1
                if Root.allSecond_x == 60:
                    Root.allSecond_x = 0
                    Root.min_x += 1
                Root.m = Root.allSecond // 60  # 分钟
                Root.sec = Root.allSecond % 60  # 秒
                time_label['text'] = "%02d:%02d" % (Root.m, Root.sec)
                play_button.config(state="disabled")
                Root.h += 1
                # 创建一个Label用于显示视频流

                if Root.h == 60:
                    Root.minn += 1
                    Root.h = 0
                if Root.minn >= 60:
                    Root.minn = 60
                    Root.h = 0
                if Root.allSecond == 0:
                    root.after_cancel(Root.id)
                    messagebox.showerror('提示', "倒计时结束！")
                    Root.star = False
                else:
                    Root.id = root.after(1000, star_exam)

        root = Tk()
        root.title("一零九驾驶考试系统")
        root.geometry(f"{Root.W}x{Root.H}+50+50")
        video_label = Label(root)
        print(Root.star)
        video_label.place(x=Root.W + 10000, y=10)

        toast = ToastNotification(
            title="一零九提醒您",
            message="欢迎使用一零九在线考试系统",
            duration=8000,
        )
        zhuti = ['cosmo', 'flatly', 'journal', 'lumen', 'minty', 'pulse', 'sandstone', 'united', 'morph', 'solar',
                 'superhero',
                 'darkly', 'cyborg', 'vapor']

        toast.show_toast()
        style = Style(theme=zhuti[11])
        root = style.master

        time_label = Label(root, text="00:00", font=("", "30"))
        time_label.place(x=65, y=10)

        play_button = Button(root, text="开始考试", font=("", "20"), command=star_exam)
        play_button.place(x=50, y=80, width=160)

        back_button = Button(root, text="返回", font=("", "20"))
        back_button.place(x=50, y=160, width=160)

        # 100个序号
        label100_label = Label(root, text=f"总数\n{number_excel[0]}/100", font=("", "20"))
        label100_label.place(x=80, y=250)

        # 问题栏
        problem_text = Text(root, font=("", "20"))
        problem_text.place(x=300, y=30, width=700, height=300)
        problem_text.insert(INSERT, problem_excel[0])
        problem_text.config(state="disabled")

        A_button = Button(root, text=f"   {A_excel[0]}", anchor="w", command=a, font=("", "15"))
        A_button.place(x=100, y=400, width=1000, height=50)
        A_button.config(state="disabled")

        B_button = Button(root, text=f"   {B_excel[0]}", anchor="w", command=b, font=("", "15"))
        B_button.place(x=100, y=460, width=1000, height=50)
        B_button.config(state="disabled")

        C_button = Button(root, text=f"   {C_excel[0]}", anchor="w", command=c, font=("", "15"))
        C_button.place(x=100, y=520, width=1000, height=50)
        C_button.config(state="disabled")

        D_button = Button(root, text=f"   {D_excel[0]}", anchor="w", command=d, font=("", "15"))
        D_button.place(x=100, y=580, width=1000, height=50)
        D_button.config(state="disabled")

        next_question_button = Button(root, text="下一题", command=next_question, font=("", "15"))
        next_question_button.place(x=1200, y=450, width=150, height=50)
        next_question_button.config(state="disabled")

        previous_question_button = Button(root, text="上一题", command=previous_question, font=("", "15"))
        previous_question_button.place(x=1400, y=450, width=150, height=50)
        previous_question_button.config(state="disabled")

        submit_button = Button(root, text="提交", command=submit, font=("", "15"))
        submit_button.place(x=1200, y=550, width=150, height=50)
        submit_button.config(state="disabled")

        quit_button = Button(root, text="退出考试", command=quit, font=("", "15"))
        quit_button.place(x=1400, y=550, width=150, height=50)
        quit_button.config(state="normal")

        buttons = []
        buttonX = 0
        buttonY = 660
        for button in range(100):
            buttonX += 60
            for i in range(1, 4):
                if button == 27 * i:
                    buttonX = 60
                    buttonY = buttonY + 60

            button = Button(root, text=f"{button + 1}", highlightthickness=1, command=lambda l=button: button_100(l),
                            font=("", "12"))
            button.place(x=buttonX - 60, y=buttonY, width=60, height=60)
            buttons.append(button)
            button.config(state="disabled")

        # 更新视频流的函数
        def update_video():
            ret, frame = cap.read()
            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                # 检测人脸
                faces = face_cascade.detectMultiScale(frame, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

                # 在人脸周围画矩形框
                for (x, y, w, h) in faces:
                    cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)

                image = Image.fromarray(frame)
                image = ImageTk.PhotoImage(image)
                video_label.config(image=image)
                video_label.image = image  # 保持对image的引用
            root.after(1, update_video)  # 1毫秒后再次更新

        # 启动视频更新循环
        update_video()

        root.mainloop()  # 关闭窗口

        # 当退出时释放摄像头资源
        cap.release()


if __name__ == '__main__':
    Root()
